<?php

/*	Vulpes-backend - Web-based managegent for wireless internet providers.
	Copyright (C) 2007 LinFox Serviços em Informática Ltda.

	This file is part of the Vulpes backend.

	Vulpes-backend is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	Vulpes-backend is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

 	Please note that any front-end (client application) that is distributed
	along with the Vulpes back-end, such as the Vulpes front-end by LinFox,
	is subject to it's correspending licene. */

function get($var)
{
	global $db;

	if		(isset($_POST[$var]))	return $db->real_escape_string($_POST[$var]);
	elseif	(isset($_GET[$var]))	return $db->real_escape_string($_GET[$var]);
	else							return false;
}

/**
 * Recreates tc and iptables rules
 * @todo create seperate section for interfaces.
 */
function iptables_refresh($restart_dhcpd = true, $echo = false)
{
	global $config, $db;

	$dhcpd_conf = stripcslashes($config->dhcpd_header);
	$out_iface = $config->iface;
	$commands = array();
	$used_interfaces = array();
	$iptables = '';
	$iptables_nat = '';
	$iptables_mangle = '';
	$day = strtolower(date('l'));
	$time = date('H:i:s');
	if ($day == 'saturday' || $day == 'sunday') {
		$week_part = 'weekend';
	} else {
		$week_part = 'workday';
	}
	$contracts_sql = '
		SELECT
			`contracts`.`handle`,
			`contracts`.`ip`,
			`contracts`.`mac`,
			`contracts`.`status`,
			`clients`.`username`,
			`clients`.`active`,
			`plans`.`interface`,
			`plans`.`download`,
			`plans`.`upload`,
			`plans`.`auth`,
			`schedules`.`upload` AS `upload_sched`,
			`schedules`.`download` AS `download_sched`
		FROM `contracts`
		INNER JOIN `clients` ON (
			`contracts`.`client_username` = `clients`.`username` )
		INNER JOIN `plans` ON (
			`plans`.`id` = `contracts`.`plan_id`)
		INNER JOIN `schedules` ON (
			`schedules`.`plan_id` = `plans`.`id` )
		WHERE ( `schedules`.`day` = "'.$day.'"
			OR `schedules`.`day` = "'.$week_part.'"
			OR `schedules`.`day` = "all" )
			AND `schedules`.`start` < "'.$time.'"
			AND `schedules`.`end` > "'.$time.'"';
	$contracts_result = $db->query($contracts_sql);
	$commands[] = 'sudo /sbin/tc qdisc del dev '.$out_iface.' root';
	$commands[] = 'sudo /sbin/tc qdisc add dev '.$out_iface.' root handle 1: htb default 3';

	while ($contract = $contracts_result->fetch_object()) {

		if($contract->status == 'L' && $contract->ip != '' && $contract->mac != '') {

			$dhcpd_conf .= '
				host '.$contract->username.$contract->handle.' {
					hardware ethernet '.$contract->mac.';
					fixed-address '.$contract->ip.';
				}';
			// Create a tc qdisc for every interface that passes by
			if (!$used_interfaces[$plan->interface]) {
				$commands[] = 'sudo /sbin/tc qdisc del dev '.$contract->interface.' root';
				$commands[] = 'sudo /sbin/tc qdisc add dev '.$contract->interface.' root handle 1: htb default 3';
				$used_interfaces[$plan->interface] = true;
			}
			if ($contract->active || !$contract->auth) {
				$commands[] = 'sudo /sbin/tc class add dev '.$out_iface.' parent 1:0 classid 1:1'.$contract->handle.' htb rate '.$contract->upload.'kbit ceil 0 burst 15k';
				$commands[] = 'sudo /sbin/tc qdisc add dev '.$out_iface.' parent 1:1'.$contract->handle.' handle 1'.$contract->handle.': sfq perturb 10';
				$commands[] = 'sudo /sbin/tc class add dev '.$contract->interface.' parent 1:0 classid 1:2'.$contract->handle.' htb rate '.$contract->download.'kbit ceil 0 burst 15k';
				$commands[] = 'sudo /sbin/tc qdisc add dev '.$contract->interface.' parent 1:2'.$contract->handle.' handle 2'.$contract->handle.': sfq perturb 10';
				$commands[] = 'sudo /sbin/tc filter add dev '.$out_iface.' parent 1:0 protocol ip prio 1 handle 3'.$contract->handle.' fw flowid 1:1'.$contract->handle;
				$commands[] = 'sudo /sbin/tc filter add dev '.$contract->interface.' parent 1:0 protocol ip prio 1 u32 match ip dst '.$contract->ip.' flowid 1:2'.$contract->handle;
				$iptables_nat .= "-I PREROUTING -s ".$contract->ip." -p tcp --dport 80 -j REDIRECT --to-port 3128\n";
				$iptables_mangle .= "-A PREROUTING -s ".$contract->ip." -j MARK --set-mark 3".$contract->handle."\n";
				$iptables_filter .= "-A FORWARD -s ".$contract->ip." -m mac --mac-source ".$contract->mac." -j ACCEPT\n";
				$iptables_filter .= "-A FORWARD -d ".$contract->ip." --in-interface ".$contract->interface." -j ACCEPT\n";
				$iptables_filter .= "-A INPUT -s ".$contract->ip." -m mac --mac-source ".$contract->mac." -j ACCEPT\n";
				$iptables_filter .= "-A OUTPUT -s ".$contract->ip." -j ACCEPT\n";
			}

		}

	}
	$contracts_result->free();

	$iptables = stripcslashes($config->iptables);
	$iptables = str_replace('{vulpes_nat}',$iptables_nat,$iptables);
	$iptables = str_replace('{vulpes_mangle}',$iptables_mangle,$iptables);
	$iptables = str_replace('{vulpes_filter}',$iptables_filter,$iptables);
	$file_iptables = fopen('/etc/firewall','w');
	fwrite($file_iptables,$iptables);
	fclose($file_iptables);
	exec('sudo /sbin/iptables-restore < /etc/firewall');

	foreach ($commands as $command) {
		if ($echo) echo $command."\n";
		exec($command, $messages, $error);
	}
	$file = fopen('/etc/dhcp3/dhcpd.conf','w');
	fwrite($file, $dhcpd_conf);
	fclose($file);
	if ($restart_dhcpd)
		exec('sudo /etc/init.d/dhcp3-server restart');
}

function xml_iterate($object, $key_name = false)
{
	if (is_array($object) || is_object($object))
	{
		if ($key_name)
			$result = '<'.$key_name.'>';
		else
			$result = ''; 

		foreach ($object as $key => $value)
		{
			if (!is_array($value) && !is_object($value))
			{
				$result .= '<'.str_underline($key).'>' .$value. '</'.str_underline($key).'>';
			}
		}
		
		if ($key_name)
			$result .= '</'.$key_name.'>';
 
		return $result;
	}
	else
	{
		return false;
	}
}

function xml_iterate_recursive($object, $key_name = false)
{
	if ($key_name)
		$result = '<'.$key_name.'>';
	else
		$result = ''; 

	if (is_array($object) || is_object($object))
	{
		foreach ($object as $key => $value)
		{
			if (is_array($value) || is_object($value))
			{
				$result .= xml_iterate($value, $key);
			}
			else
			{
				$result .= '<'.str_underline($key).'>' .$value. '</'.str_underline($key).'>';
			}
		}
		
		if ($key_name)
			$result .= '</'.$key_name.'>';
 
		return $result;
	}
	else
	{
		return false;
	}
}


function str_underline($string)
{
	return str_replace(' ', '_', $string);
}

function str_is_ip($string)
{
	if (eregi('^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]{1,2}){0,1}$', $string))
		return true;
	else
		return false;
}

/**
* Looks up the ARP cache table and returns it in an array.
**/
function arp($arp_file = '/proc/net/arp', $log = false)
{
	$arp = file($arp_file);
	$result = array();
	foreach($arp as $row_number => $row) {
		if ($row_number == '0') {
			$keys = split(" [ ]+", $row);
		} else {
			$values = split(" [ ]+", $row);
			foreach ($values as $key => $value) {
				$result[$row_number][str_underline(strtolower($keys[$key]))] = $value;
			}
		}
	}
	return $result;
}

?>
